"""Common footer for bot activity."""
import argparse
import dataclasses
import os
import typing

import sentry_sdk

from cki_lib import misc
from cki_lib import yaml


@dataclasses.dataclass
class Context:  # pylint: disable=too-many-instance-attributes
    """Footer context."""

    name: str
    faq_name: str = ''
    faq_url: str = ''
    slack_name: str = ''
    slack_url: str = ''
    source_code: str = ''
    documentation_url: str = ''
    new_issue_url: str = ''


def _escape_link(url):
    """Return an escaped link."""
    return url.replace(' ', '%20').replace('[', '%5B').replace(']', '%5D')


def _only_link(_, url):
    """Return only the link without any formatting."""
    return _escape_link(url)


class Footer:
    """Handle footer generation."""

    GITLAB_PREFIX = '\n\n---\n\n<small>'
    GITLAB_SUFFIX = '</small>\n'

    def __init__(self, context=None):
        """Instantiate the instance."""
        self.context = context or Context(**yaml.load(
            contents=os.environ.get('FOOTER_CONFIG'),
            file_path=os.environ.get('FOOTER_CONFIG_PATH'),
        ))

    @staticmethod
    def text_link(text, url):
        """Return a link for a text field."""
        return f'{text}: {_escape_link(url)}'

    @staticmethod
    def jira_link(text, url):
        """Return a Jira-formatted link."""
        return f'[{text}|{_escape_link(url)}]'

    @staticmethod
    def gitlab_link(text, url):
        """Return a GitLab markdown-formatted link."""
        return f'[{text}]({_escape_link(url)})'

    def comment_footer(
        self,
        *,
        what=None,
        link_formatter=_only_link,
        prefix='',
        suffix='\n',
        first_prefix='',
        first_suffix='',
        line_prefix='',
        line_suffix='',
        line_join='',
    ):
        # pylint: disable=too-many-arguments,too-many-positional-arguments
        """Return a bot footer."""
        now = misc.now_tz_utc().replace(tzinfo=None).isoformat(' ', 'minutes')
        first = f'{(what or "created").title()} {now} UTC by {self.context.name}'
        lines = []
        if self.context.faq_name and self.context.faq_url:
            lines.append(link_formatter(self.context.faq_name, self.context.faq_url))
        if self.context.slack_name and self.context.slack_url:
            lines.append(link_formatter(f'Slack {self.context.slack_name}', self.context.slack_url))
        if self.context.source_code:
            lines.append(link_formatter('Source', self.context.source_code))
        if self.context.documentation_url:
            lines.append(link_formatter('Documentation', self.context.documentation_url))
        if self.context.new_issue_url:
            lines.append(link_formatter('Report an issue', self.context.new_issue_url))
        return (
            prefix +
            first_prefix + first + first_suffix + line_join +
            line_join.join(line_prefix + line + line_suffix for line in lines) +
            suffix
        )

    def text_footer(self, what=None):
        """Return a bot footer suitable for a plain text box."""
        return self.comment_footer(
            what=what,
            link_formatter=self.text_link,
            prefix='\n----------------------------------------\n\n',
            suffix='',
            first_prefix='',
            first_suffix=':\n',
            line_prefix='- ',
            line_suffix='\n',
        )

    def jira_footer(self, what=None):
        """Return a bot footer suitable for a Jira comment."""
        return self.comment_footer(
            what=what,
            link_formatter=self.jira_link,
            prefix='----\n',
            line_join=' - ',
        )

    def gitlab_footer(self, what=None):
        """Return a bot footer suitable formatted via GitLab markdown."""
        return self.comment_footer(
            what=what,
            link_formatter=self.gitlab_link,
            prefix=self.GITLAB_PREFIX,
            suffix=self.GITLAB_SUFFIX,
            line_join=' - ',
        )


def main(argv: typing.Optional[typing.List[str]] = None) -> None:
    """Generate the common footer for bot activity."""
    parser = argparse.ArgumentParser(description='Generate the common footer for bot activity',
                                     formatter_class=argparse.ArgumentDefaultsHelpFormatter)
    parser.add_argument('--format', default='text', choices=('text', 'jira', 'gitlab'),
                        help='Footer format')
    parser.add_argument('--what', default='created', choices=('created', 'updated'),
                        help='Whether the footer was created or updated')
    args = parser.parse_args(argv)

    footer = Footer()
    return getattr(footer, f'{args.format}_footer')(what=args.what)


if __name__ == '__main__':
    misc.sentry_init(sentry_sdk)
    print(main(), end='')
